﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace ICeFramework.Utilities.TCPComm
{
    public class TCPClient
    {
        private NetworkStream clientStream;
        private TcpClient tcpClient = null;

        public event ServerResponseHandler ServerResponse;
        public event EventHandler Connected;
        public event ClientErrorHandler ClientError;

        private string _hostName;
        public string HostName
        {
            get { return _hostName; }
        }

        private int _port;
        public int Port
        {
            get { return _port; }
        }

        public bool IsConnected
        {
            get { return tcpClient != null ? tcpClient.Connected : false; }
        }

        public TCPClient(string hostName, int port)
        {
            _hostName = hostName;
            _port = port;
        }

        public void Connect()
        {
            try
            {
                tcpClient = new TcpClient(_hostName, _port);
                OnConnected();

                clientStream = tcpClient.GetStream();
            }
            catch (Exception ex)
            {
                OnClientError(new ClientErrorEventArgs(ex));
            }
        }

        public void Send(object data)
        {
            try
            {
                TCPRequest req = new TCPRequest(ClientRequestType.Post, data);
                byte[] sendBytes = Serialization.BinarySerialization.GetBytes(req);
                clientStream.Write(sendBytes, 0, sendBytes.Length);
                HandleResponse();
            }
            catch (Exception ex)
            {
                OnClientError(new ClientErrorEventArgs(ex));
            }
        }

        private void HandleResponse()
        {
            byte[] data = new byte[1024];
            int ret = clientStream.Read(data, 0, data.Length);
            TCPResponse response = (TCPResponse)Serialization.BinarySerialization.GetObject(data);
            OnServerResponse(new ServerResponseEventArgs(response));
        }

        public virtual void OnConnected()
        {
            if (Connected != null)
            {
                Connected(this, EventArgs.Empty);
            }
        }

        public virtual void OnServerResponse(ServerResponseEventArgs e)
        {
            if (ServerResponse != null)
            {
                ServerResponse(this, e);
            }
        }

        public virtual void OnClientError(ClientErrorEventArgs e)
        {
            if (ClientError != null)
            {
                ClientError(this, e);
            }
        }
    }
}
